/*module add(	input sysclk,
		input [16:0] data1,
		input [16:0] data2,
		input [2:0] position1,
		input [2:0] position2,
		input [2:0]enable,
		input done,
		output reg [32:0] result,
		output reg [2:0] position,
		output reg suc );


parameter init=3'b000,start=3'b001,process1=3'b010,process2=3'b011,cal=3'b100,finish=3'b101;
reg [31:0] opnum1;
reg [31:0] opnum2;
reg [2:0] shiftbit1;
reg [2:0] shiftbit2;
reg [2:0] state;
reg [2:0] nstate;

initial begin
	nstate <= init;
end

always @(*) begin
	state = nstate;
end

always @(posedge sysclk) begin
	case (state)
		init: begin
			suc<=1'b0;
			if (enable==3'b001) begin
				opnum1 <= data1[15:0];
				opnum2 <= data2[15:0];
				shiftbit1 <= position1;
				shiftbit2 <= position2;
				nstate <= start;
			end
			else begin
				nstate <= init;
			end
		    end
		start:	begin
			if (data1[16]^data2[16]) begin
				if (data1[15:0]>data2[15:0]) result[32] = data1[16];
				else result[32] = data2[16];
			end
			else result[32] = data1[16];
			nstate <= process1;
			end
			
		process1:begin
			if (shiftbit1) begin
				opnum1 <= opnum1<<4;
				shiftbit1 <= shiftbit1-1'b1;
			end
			else begin
				nstate <= process2;
			end
			end
		process2:begin
			if (shiftbit2) begin
				opnum2 <= opnum2<<4;
				shiftbit2 <= shiftbit2-1'b1;
			end
			else nstate <= cal;
			end
		cal:	begin
			if (result[32]) begin
				if (opnum1>opnum2) result[31:0] <= opnum1-opnum2;
				else result[31:0] <= opnum2-opnum1;
			end
			else result[31:0] <= opnum1+opnum2;
			if (position1>position2) position <= position1;
			else position <= position2;
			suc <= 1'b1;
			nstate <= finish;
			end
		finish: begin
			if (done) begin
				suc = 1'b0;
				nstate <= init;
			end
			else
				nstate <= finish;
			end
	endcase
end

endmodule*/
module add3(	input [15:0]data1,
		input [15:0]data2,
		input [1:0]position1,
		input [1:0]position2,
		input isNeg1,
		input isNeg2,
		input [2:0]enable,
		input done,
		input reset,
		input sysclk,
		output reg [1:0] position,
		output reg [15:0]result,
		output reg isNeg,
		output reg suc);


parameter init=3'b000,prepare=3'b001,prepare1=3'b010,start=3'b011,judgement=3'b100,finish=3'b101;
reg [2:0]state;
reg [2:0]nstate;
reg [2:0] counter;
reg [2:0] shiftbit;
reg [25:0] data1_temp;
reg [25:0] data2_temp;
reg [25:0] result_temp;
reg flag1;
reg flag2;


reg [3:0] highPos_result;

initial begin
	nstate = init;
end

always @(*) begin
	state = nstate;
end


always @(posedge sysclk) begin
	if (reset) begin
		result = 16'b0;
		isNeg = 1'b0;
		suc = 1'b0;
		position = 1'b0;
		counter = 3'b0;
		data1_temp = 25'b0;
		data2_temp = 25'b0;
		result_temp = 25'b0;
		flag1 = 1'b0;
		flag2 = 1'b0;
		shiftbit = 2'b0;
		nstate = init;
	end
	else begin
		case(state)
			init:	begin
				if (enable==3'b001) begin
					result = 16'h0;
					isNeg = 1'b0;
					suc = 1'b0;
					position = 1'b0;
					counter = 3'b0;
					data1_temp = 25'b0;
					data2_temp = 25'b0;
					result_temp = 25'b0;
					flag1 = 1'b0;
					flag2 = 1'b0;
					shiftbit = 2'b0;
					nstate = prepare;
					end
				else begin
					nstate = init;
					suc = 1'b0;
					end
				end

			prepare: begin
					data1_temp = data1;
					data2_temp = data2;
					if (position1 > position2) begin
						counter = position1 - position2;
						shiftbit = position1;
						flag2 = 1'b1;
						end
					else begin
						counter = position2 - position1;
						shiftbit = position2;
						flag1 = 1'b1;
						end	
					nstate = prepare1;
				end

			prepare1: begin
					if (counter) begin
						if (flag1) begin
							data1_temp = data1_temp * 10;
							counter = counter - 1'b1;
							end
						if (flag2) begin
							data2_temp = data2_temp * 10;
							counter = counter - 1'b1;
							end
						nstate = prepare1;
						end
					else
						nstate = start;
				end	
			start:	begin
					if (isNeg1^isNeg2) begin
						if (data1_temp >= data2_temp) begin
							isNeg = isNeg1;
							result_temp = data1_temp - data2_temp;
						end
						else begin
							isNeg = isNeg2;
							result_temp = data2_temp - data1_temp;
						end
					end
					else begin
						isNeg = isNeg1;
						result_temp = data1_temp + data2_temp;
					end
					
					nstate = judgement;
				end

			judgement: begin
					if (result_temp> 25'd999_999)
						highPos_result = 7;
					else if (result_temp > 25'd99_999)
						highPos_result = 6;
					else if (result_temp > 25'd9_999)
						highPos_result = 5;
					else if (result_temp > 25'd999)
						highPos_result = 4;
					else if (result_temp > 25'd99)
						highPos_result = 3;
					else if (result_temp > 25'd9)
						highPos_result = 2;
					else if (result_temp > 25'd0)
						highPos_result = 1;
					else
						highPos_result = 0;
						
					case (highPos_result)
						4'd7:begin
								position = 2'd0;
								result_temp = ( ( (result_temp>>1) + (result_temp>>7)+ (result_temp>>8)+ (result_temp>>12)+ (result_temp>>15)+ (result_temp>>16)) >>9 ); 
							end
						4'd6:begin
								result_temp = ( ( (result_temp>>1) + (result_temp>>3)+ (result_temp>>7)+ (result_temp>>8)+ (result_temp>>9)+ (result_temp>>10)+ (result_temp>>12)+ (result_temp>>14)+ (result_temp>>15)+ (result_temp>>16)+ (result_temp>>17) )  >>6 );
								case(shiftbit)
									3'd3:begin
											position = 2'd1;
										end
									3'd2, 3'd1, 3'd0:begin
											position = 2'd0;
										end
								endcase
							end
						4'd5:begin
								result_temp = ( ( (result_temp>>1) + (result_temp>>2)+ (result_temp>>5)+ (result_temp>>6)+ (result_temp>>9)+ (result_temp>>10)+ (result_temp>>12)) >>3 );
								case(shiftbit)
									3'd3:begin
											position = 2'd2;
										end
									3'd2:begin
											position = 2'd1;
										end
									3'd1, 3'd0:begin
											position = 2'd0;
										end
								endcase
							end
						4'd4:begin
								case(shiftbit)
									3'd3:begin
											position = 2'd3;
										end
									3'd2:begin
											position = 2'd2;
										end
									3'd1:begin
											position = 2'd1;
										end
									3'd0:begin
											position = 2'd0;
										end
								endcase
							end
						4'd3:begin
								case(shiftbit)
									3'd3:begin
											position = 2'd3;
										end
									3'd2:begin
											position = 2'd2;
										end
									3'd1:begin
											position = 2'd1;
										end
									3'd0:begin
											position = 2'd0;
										end
								endcase
							end
						4'd2:begin
								case(shiftbit)
									3'd3:begin
											position = 2'd3;
										end
									3'd2:begin
											position = 2'd2;
										end
									3'd1:begin
											position = 2'd1;
										end
									3'd0:begin
											position = 2'd0;
										end
								endcase
							end
						4'd1:begin
								case(shiftbit)
									3'd3:begin
											position = 2'd3;
										end
									3'd2:begin
											position = 2'd2;
										end
									3'd1:begin
											position = 2'd1;
										end
									3'd0:begin
											position = 2'd0;
										end
								endcase
							end
						4'd0:begin
								position = 2'd0;
								result_temp = 25'b0;
							end
					endcase
						
						
					result = result_temp[15:0];
					suc = 1'b1;
					nstate = finish;
				end

			finish:	begin	
					if (done) begin
						suc = 1'b0;
						nstate = init;
					end
					else 
						nstate = finish;
				end
		endcase
	end
end

endmodule
